﻿using Aiming.IteratorTasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

namespace TestIteratorTasks
{
	[TestClass]
	public class TaskCompletionSourceTest
	{
		[TestMethod]
		public void SetResultするまではRunnint状態_後はIsCompleted()
		{
			var tcs = new TaskCompletionSource<int>();

			var task = tcs.Task;
			CheckRunning(task);

			tcs.SetResult(100);

			Assert.IsTrue(task.IsCompleted);
			Assert.AreEqual(100, task.Result);
		}

		private static void CheckRunning(Task<int> task)
		{
			for (int i = 0; i < 100; i++)
			{
				Assert.IsTrue(task.Status == TaskStatus.Running);
			}
		}

		[TestMethod]
		public void SetExceptionするまではRunnint状態_後はIsFaulted()
		{
			var tcs = new TaskCompletionSource<int>();

			var task = tcs.Task;
			CheckRunning(task);

			const string errorMessage = "some error";
			tcs.SetException(new Exception(errorMessage));

			Assert.IsTrue(task.IsFaulted);

			try
			{
				var result = task.Result;

				Assert.Fail("例外が発生していないとおかしい");
			}
			catch (Exception ex)
			{
				Assert.AreEqual(errorMessage, ex.Message);
			}
		}

		[TestMethod]
		public void SetCanceldするまではRunnint状態_後はIsFaulted()
		{
			var tcs = new TaskCompletionSource<int>();

			var task = tcs.Task;
			CheckRunning(task);

			tcs.SetCanceled();

			Assert.IsTrue(task.IsFaulted);

			try
			{
				var result = task.Result;

				Assert.Fail("例外が発生していないとおかしい");
			}
			catch (AggregateException ex)
			{
				Assert.IsTrue(ex.Exceptions.First() is TaskCanceledException);
			}
		}
	}
}
